<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div></div>
    <div></div>
    <div></div>
</body>

</html>
<script>
    // 扩展运算符(spread)是三个点(...) 好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列.
    console.log(...[1, 2, 3]);    //1,2,3
    console.log(1, 2, ...[4, 5, 6], 7, 8);    //1,2,3,4,5,6,7,8
    console.log([...document.querySelectorAll('div')]);  //[<div>, <div>, <div>]

    // 该运算符主要用于函数调用 该运算将一个数组,变为参数序列
    function push(array, ...items) {
        array.push(...items);
    }

    function add(x, y) {
        console.log(x + y);
    }

    const numbers = [4, 38];
    add(...numbers);    //42

    // 扩展运算符和正常的函数参数结合使用
    function f(v, w, x, y, z) { }

    const args = [0, 1];

    f(-1, ...args, 2, ...[3]);


    // 扩展运算符后面还可以放置表达式
    let x = 2;
    const arr = [...(x > 0 ? ['a'] : []), 'b'];

    // 如果扩展运算符后面是一个空数组, 则不产生任何效果.
    [...[], 1];

    // 只有函数调用的时候扩展运算符才可以放置在圆括号中, 否则会报错




    // 替代函数的apply方法: 由于扩展运算符可以展开数组, 所以不再需要apply方法, 将数组转为函数的参数了
    function f2(x, y, z) { }
    var args2 = [0, 1, 2];
    f2.apply(null, args2);

    function f3(x, y, z) { }
    let args3 = [0, 1, 2];
    f3(...args3);

    // 求出一个数组最大元素的方法
    // ES5
    Math.max.apply(null, [3, 17, 4, 5]);
    // ES6
    Math.max(...[3, 17, 4, 5]);
    // 等同于
    Math.max(3, 17, 4, 5);



</script>

<script>
    // apply 方法
    // apply方法能劫持另外一个对象的方法，继承另外一个对象的属性

    /**
    *   Function.apply(obj,args)方法能接收两个参数
    *   obj：这个对象将代替Function类里this对象
    *   args：这个是数组，它将作为参数传给Function（args-->arguments）
    */

    function Person(name, age) {    //定义一个类,人类  
        this.name = name;   //名字  
        this.age = age; //年龄 
        this.sayhello = function () { alert("hello") };
    }

    function Print() {  //显示类的属性 
        this.funcName = "Print";
        this.show = function () {
            var msg = [];
            for (var key in this) {
                if (typeof (this[key]) != "function") {
                    msg.push([key, ":", this[key]].join(""));
                }
            }
            alert(msg.join(" "));
        };
    }

    function Student(name, age, grade, school) {    //学生类 
        Person.apply(this, arguments);
        Print.apply(this, arguments);
        this.grade = grade; //年级 
        this.school = school;   //学校 
    }

    var p1 = new Person("jake", 10);
    p1.sayhello();

    var s1 = new Student("tom", 13, 6, "清华小学");
    s1.show();
    s1.sayhello();
    alert(s1.funcName);

</script>